﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK;

namespace Common {
    public class TangentSpace {
        public static unsafe void computeTangentBasis(
            List<Vector3> vertices,
            List<Vector2> uvs,
            List<Vector3> normals,

            List<Vector3> tangents,
            List<Vector3> bitangents
            ) {

            for (int i = 0; i < vertices.Count; i += 3) {
                Vector3 v0 = vertices[i];
                Vector3 v1 = vertices[i + 1];
                Vector3 v2 = vertices[i + 2];

                Vector2 uv0 = uvs[i];
                Vector2 uv1 = uvs[i + 1];
                Vector2 uv2 = uvs[i + 2];

                Vector3 deltaPos1 = v1 - v0;
                Vector3 deltaPos2 = v2 - v0;

                Vector2 deltaUv1 = uv1 - uv0;
                Vector2 deltaUv2 = uv2 - uv0;

                float r = 1.0f / (deltaUv1.X * deltaUv2.Y - deltaUv1.Y * deltaUv2.X);
                Vector3 tangent = (deltaPos1 * deltaUv2.Y - deltaPos2 * deltaUv1.Y) * r;
                Vector3 bitangent = (deltaPos2 * deltaUv1.X - deltaPos1 * deltaUv2.X) * r;

                tangents.Add(tangent);
                tangents.Add(tangent);
                tangents.Add(tangent);

                bitangents.Add(bitangent);
                bitangents.Add(bitangent);
                bitangents.Add(bitangent);
            }

            for (int i = 0; i < vertices.Count; i += 1) {
                //Vector3 n = normals[i];
                //Vector3 t = tangents[i];
                //Vector3 b = bitangents[i];

                //t = Vector3.Normalize(t - n * Vector3.Dot(n, t));
                //if (Vector3.Dot(Vector3.Cross(n, t), b) < 0.0f) {
                //    t = t * -1.0f;
                //}

                Vector3 n = normals[i];
                Vector3 t = tangents[i];
                Vector3 b = bitangents[i];

                t = Vector3.Normalize(t - n * Vector3.Dot(n, t));
                if (Vector3.Dot(Vector3.Cross(n, t), b) < 0.0f) {
                    t = t * -1.0f;
                }
                normals[i] = n;
                tangents[i] = t;
                bitangents[i] = b;
            }
        }
    }
}
